#define SC_INCLUDE_DYNAMIC_PROCESSES 	//necessary for sc_spawn() to compile

#include "systemc.h"
#include <iostream>
#include "tbb/spin_mutex.h"
#include "flops_job.h"


#define print(msg)\
        std::cout << msg << std::endl;

sc_event ef0;
sc_event ef1;
sc_event et0;
sc_event et1;

int gl_n;

void f0(){
	static int j;
        print("in f0(), with j=" << j);
        sc_log* my_log = sc_get_current_process_handle().get_log();
        if(!getenv("SILENT")) { calc::flops_job(gl_n,'#'); } else { calc::flops_job(gl_n); }
        my_log->notify(&ef0,SC_ZERO_TIME);
	if(++j >= 8)  my_log->next_trigger();
	else	     my_log->next_trigger(ef0|ef1);
}
void f1(){
	static int j;
        print("in f1(), with j=" << j);
        sc_log* my_log = sc_get_current_process_handle().get_log();
        if(!getenv("SILENT")) { calc::flops_job(gl_n,'^'); } else { calc::flops_job(gl_n); }
        my_log->notify(&ef1,SC_ZERO_TIME);
	if(++j >= 8)  my_log->next_trigger();
	else	     my_log->next_trigger(ef1);
}

void t0(){
	int j=0;
        while(1){
                print("in t0(), with j=" << j);
                sc_log* my_log = sc_get_current_process_handle().get_log();
                if(!getenv("SILENT")) { calc::flops_job(gl_n,'!'); } else { calc::flops_job(gl_n); }
                my_log->notify(&et0,SC_ZERO_TIME);
                if(++j >= 3)  wait_par();
                else	     wait_par(et0);
        }
}
void t1(){
	int j=0;
        while(1){
                print("in t1(), with j=" << j);
                sc_log* my_log = sc_get_current_process_handle().get_log();
                if(!getenv("SILENT")) { calc::flops_job(gl_n,'@'); } else { calc::flops_job(gl_n); }
                my_log->notify(&et1,SC_ZERO_TIME);
                if(++j >= 3)  wait_par();
                else	     wait_par(et1);
        }
}

int sc_main(int argc,char** argv){

        gl_n = atoi(argv[1]);
	sc_spawn_options opt;
	opt.spawn_method();
               sc_spawn(f0,"",&opt);
               sc_spawn(f1,"",&opt);
	opt.spawn_thread_par();
              sc_spawn(t0,"",&opt);
              sc_spawn(t1,"",&opt);
	sc_start();
        
        print("Bye! from main()");
	return 0;
}
